<template>
  <div class="menu-list-box">
    <el-select
      class="apps-select-box"
      v-loading="groupsLoading"
      v-model="selectedAppId"
      placeholder="请选择子系统"
    >
      <el-option-group
        v-for="group in groupsArr"
        :key="group.appGroupCode"
        :label="group.appGroupName"
      >
        <el-option
          v-for="item in group.appVOList"
          :key="item.appId"
          :label="item.appName"
          :value="item.appId"
        />
      </el-option-group>
    </el-select>
    <div class="menu-list">
      <div class="menu-tree" v-loading="treeLoading">
        <h3 class="tree-title">菜单列表</h3>
        <el-input
          placeholder="输入关键字进行过滤"
          clearable
          v-model="searchMenuKey"
        >
          <i slot="prefix" class="el-input__icon el-icon-search" />
        </el-input>
        <el-tree
          class="filter-tree"
          :data="treeData"
          :props="defaultProps"
          default-expand-all
          @node-click="handleNodeClick"
          :filter-node-method="filterNode"
          ref="tree"
        />
      </div>
      <div class="menu-add">
        <p>已配置：{{ companyList.length }}家</p>
        <el-header height="auto" class="menu-add-header">
          <el-input
            v-model="searchCompanyKey"
            class="search-input"
            @change="searchCompanyByName"
            placeholder="请输入"
          />
          <el-button type="primary" @click.stop="addCompanyBtn"
            >添加企业</el-button
          >
          <el-button
            type="danger"
            v-if="
              treeSelected &&
                (!treeSelected.children || !treeSelected.children.length)
            "
            @click.stop="delAllCompany"
            >删除全部</el-button
          >
        </el-header>
        <el-main v-loading="companyListLoading">
          <el-tag
            v-for="(item, index) in companyList"
            :key="item.companyId"
            @close="delOneCompany(item.companyId, index)"
            :closable="
              treeSelected &&
                (!treeSelected.children || !treeSelected.children.length)
            "
            >{{ item.companyName }}</el-tag
          >
          <p v-show="!companyList.length" class="no-data">暂无数据</p>
        </el-main>
      </div>
    </div>
    <el-dialog
      title="添加企业"
      :visible.sync="dialog.visible"
      @closed="addCompanyClosed"
      width="400px"
    >
      <div class="add-company-dialog" v-loading="dialog.loading">
        <el-input
          placeholder="请输入"
          clearable
          @change="getNoMenuCompany(dialog.searchKey)"
          v-model="dialog.searchKey"
        >
          <i slot="prefix" class="el-input__icon el-icon-search" />
        </el-input>
        <el-checkbox
          class="dialog-checked-all"
          @change="selectAllCompany"
          v-model="dialog.checked"
          >全选</el-checkbox
        >
        <el-checkbox-group class="checkbox-box" v-model="dialog.checkList">
          <el-checkbox
            :key="index"
            v-for="(item, index) in dialog.companyList"
            :label="item"
            >{{ item.companyName }}</el-checkbox
          >
        </el-checkbox-group>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click.stop="dialog.visible = false">取 消</el-button>
        <el-button
          type="primary"
          :loading="dialog.btnLoading"
          @click.stop="addCompanyList"
          >确 定</el-button
        >
      </span>
    </el-dialog>
  </div>
</template>
<script>
import {hasIn} from 'lodash'
import {getIdByTree} from '@const/utils.js'
import {
  ucAppGroupGetAll,
  getAppResourceByAppId,
  getCompanyByAppResourceId,
  getAllCompany,
  addRelationCompany,
  deleteAllRelationCompanyByAppResourceIdList,
  deleteRelationCompanyByAppResourceIdListAndCompanyId
} from '@const/api_staffCenter.js'
export default {
  name: 'MenuConfig',
  data() {
    return {
      selectedAppId: '', // 选中的app
      groupsArr: [],
      searchMenuKey: '', // 左侧的搜索内容
      groupsLoading: false, // 子系统组loading
      treeLoading: false, // 左侧树的loading事件
      companyListLoading: false, // 右侧公司的列表
      defaultProps: {
        children: 'children',
        label: 'appResourceName'
      },
      treeData: [],
      treeSelected: null, // 选中的树节点
      companyList: [], // 公司列表
      curSelectNode: null,
      searchCompanyKey: '', // 右边搜索的输入框
      dialog: {
        visible: false,
        loading: false,
        btnLoading: false,
        searchKey: '',
        checked: false,
        companyList: [],
        checkList: []
      }
    }
  },
  created() {
    // 获取资源类型
    this.getMenuType(() => {
      this.getTreeData()
    })
  },
  watch: {
    searchMenuKey(val) {
      this.$refs.tree.filter(val)
    },
    'dialog.checkList': {
      handler(arr) {
        if (arr.length === this.dialog.companyList.length) {
          this.dialog.checked = true
        } else {
          this.dialog.checked = false
        }
      }
    },
    selectedAppId(val) {
      this.getTreeData()
    }
  },
  methods: {
    filterNode(value, data) {
      if (!value) return true
      return data.appResourceName.indexOf(value) !== -1
    },
    selectAllCompany(flag) {
      if (flag) {
        this.dialog.checkList = this.dialog.companyList
      } else {
        this.dialog.checkList = []
      }
    },
    // 获取第一个分组，第一个系统的code
    setDefaultApp(arr) {
      try {
        this.selectedAppId = arr[0].appVOList[0].appId
        // eslint-disable-next-line no-empty
      } catch (err) {}
    },
    // 获取资源类型
    getMenuType(fn = () => {}) {
      this.groupsLoading = true
      this.treeLoading = true
      this.$axios({
        method: 'get',
        url: ucAppGroupGetAll
      })
        .then(res => {
          this.groupsArr = hasIn(res, ['data', 'payload'])
            ? res.data.payload
            : []
          this.setDefaultApp(this.groupsArr)
          fn()
        })
        .finally(() => {
          this.groupsLoading = false
        })
    },
    // 根据企业类型code获取资源树
    getTreeData() {
      this.treeLoading = true
      this.$axios({
        method: 'get',
        url: getAppResourceByAppId,
        params: {
          appId: this.selectedAppId
        }
      })
        .then(res => {
          this.treeData = hasIn(res, ['data', 'payload'])
            ? res.data.payload
            : []
        })
        .finally(() => {
          this.treeLoading = false
        })
    },
    // get左侧的公司数据
    getMenuCompany(id, name) {
      this.companyListLoading = true
      this.$axios({
        method: 'post',
        url: getCompanyByAppResourceId,
        data: {
          appResourceId: id,
          companyName: name
        }
      })
        .then(res => {
          this.companyList = hasIn(res, ['data', 'payload'])
            ? res.data.payload
            : []
        })
        .finally(() => {
          this.companyListLoading = false
        })
    },
    // 根据节点，迭代所有的id
    getAllIdArr(node) {
      let arr = []
      function iteration(node) {
        arr.push(node.data.appResourceId)
        if (node.data.parentAppResourceId !== '-1' && node.parent) {
          iteration(node.parent)
        }
      }
      iteration(node)
      return arr
    },
    // 选中左侧的树结构
    handleNodeClick(obj, node) {
      this.curSelectNode = node
      this.treeSelected = obj
      this.getMenuCompany(obj.appResourceId, '')
    },
    // 根据名称模糊搜索公司
    searchCompanyByName(val) {
      this.getMenuCompany(this.treeSelected.appResourceId, val)
    },
    // 添加企业按钮
    addCompanyBtn() {
      if (!this.treeSelected) {
        this.$message({type: 'warning', message: '请在左侧选择一个资源节点'})
        return
      }
      this.dialog.visible = true
      this.getNoMenuCompany()
    },
    // 添加公司弹框关闭的回调
    addCompanyClosed() {
      this.dialog.searchKey = ''
      this.dialog.checkList = []
    },
    // 获取该节点没有权限的企业
    getNoMenuCompany(name = '') {
      this.dialog.loading = true
      this.$axios({
        url: getAllCompany,
        method: 'post',
        data: {
          appResourceId: this.treeSelected.appResourceId,
          companyName: name
        }
      })
        .then(res => {
          this.dialog.companyList = hasIn(res, ['data', 'payload'])
            ? res.data.payload
            : []
        })
        .finally(() => {
          this.dialog.loading = false
        })
    },
    // 添加企业
    addCompanyList() {
      this.btnLoading = true
      this.$axios({
        url: addRelationCompany,
        method: 'post',
        data: {
          companyAndAppResourceIdList: this.dialog.checkList.map(item => {
            return {
              companyId: item.companyId,
              companyName: item.companyName
            }
          }),
          appResourceIdList: this.getAllIdArr(this.curSelectNode), // 子系统资源id集合
          appId: this.selectedAppId
        }
      })
        .then(res => {
          this.dialog.visible = false
          this.getMenuCompany(this.treeSelected.appResourceId, '')
        })
        .finally(() => {
          this.btnLoading = false
        })
    },
    // 删除当前菜单所有公司按钮
    delAllCompany() {
      if (!this.treeSelected) {
        this.$message({type: 'warning', message: '请在左侧选择一个资源节点'})
        return
      }
      this.$confirm(
        '此操作将永久删除该菜单及其下级菜单所有企业的菜单权限, 是否继续?',
        '提示',
        {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }
      ).then(() => {
        this.companyListLoading = true
        this.$axios({
          url: deleteAllRelationCompanyByAppResourceIdList,
          method: 'post',
          data: {
            appResourceIdList: [this.treeSelected.appResourceId]
          }
        })
          .then(res => {
            this.companyList = []
          })
          .finally(() => {
            this.companyListLoading = false
          })
      })
    },
    // 删除单个公司
    delOneCompany(id, index) {
      this.$confirm('此操作将永久删除该菜单权限, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.companyListLoading = true
        this.$axios({
          url: deleteRelationCompanyByAppResourceIdListAndCompanyId,
          method: 'post',
          data: {
            companyId: id,
            appResourceIdList: [this.treeSelected.appResourceId]
          }
        })
          .then(res => {
            // 删除节点
            this.companyList.splice(index, 1)
          })
          .finally(() => {
            this.companyListLoading = false
          })
      })
    }
  }
}
</script>
<style lang="less">
@import '../m-front-common/pc/assets/var.less';

.menu-list-box {
  display: flex;
  flex-direction: column;

  .apps-select-box {
    width: 280px;
    margin-bottom: 10px;
  }

  .menu-list {
    flex: 1;
    display: flex;
    overflow: auto;

    .menu-tree {
      border: @defaultBorder;
      padding: 24px 18px;
      width: auto;
      margin-right: 20px;
      display: flex;
      flex-direction: column;

      .tree-title {
        font-size: 14px;
        line-height: 20px;
        margin-bottom: 20px;
      }

      .filter-tree {
        margin-top: 16px;
        overflow: auto;

        .el-tree-node {
          &.is-current {
            .el-tree-node__content {
              color: @hoverFontColor;
            }
          }
        }
      }
    }

    .menu-add {
      border: @defaultBorder;
      flex: 1;
      padding: 24px 20px;
      display: flex;
      flex-direction: column;

      .menu-add-header {
        display: flex;
        margin: 27px 0;
        padding: 0;

        .search-input {
          margin-right: 10px;
        }
      }

      .el-main {
        padding: 0;

        .el-tag {
          background-color: rgba(35, 113, 197, 0.1);
          border-radius: 0;
          color: @defaultFontColor;
          margin-right: 10px;
          margin-bottom: 10px;

          .el-tag__close {
            color: #fff;
            background-color: #d5dae4;
          }
        }

        .no-data {
          text-align: center;
        }
      }
    }
  }

  .add-company-dialog {
    height: 500px;
    display: flex;
    flex-direction: column;

    .dialog-checked-all {
      margin: 16px 0;
    }

    .checkbox-box {
      flex: 1;
      overflow: auto;

      .el-checkbox {
        display: block;
        margin-left: 0;
      }
    }
  }
}
</style>
